import os.path

from kj_d1.Crawl.crawl import crawl_file
from kj_d1.App.app import create_app, config_app, publish_app, get_app_key, delete_app, get_app_list
from kj_d1.Document.upload_file import upload_file_to_cos, get_file_list, get_temporary_key, FileUploadException
from kj_d1.DS.ds import ds_reply, DSReplyTypeException
from kj_d1.base.base import par_mk, sum_amt, get_num_for
from kj_d1.App.cost import get_knowledge_usage, KnowledgeUsageException, ArrearException

from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException

from time import sleep
import pandas as pd
import os
import sys
from random import randint

from loguru import logger


def get_ds_reply(stock_code):
    """

    :param stock_code_list:
    :param n_group:
    :return:
    """
    # 获取年报
    logger.info(f'{stock_code}开始抓取年报')
    file_path = crawl_file(stock_code)
    logger.info(f'{stock_code}年报抓取完成')

    # 创建app
    logger.info(f'{stock_code}创建大模型应用')
    ds_app = create_app(app_nm=stock_code)
    config_app(ds_app)

    logger.info(f'{stock_code}知识库容量校验')
    kn_us = get_knowledge_usage(ds_app)
    if float(kn_us['UsedCharSize']) / float(kn_us['AvailableCharSize']) > 0.8:
        raise KnowledgeUsageException('知识库空间不足')
    logger.info(f'{stock_code}当前知识库容量占比{float(kn_us["UsedCharSize"]) / float(kn_us["AvailableCharSize"])}')
    # 上传文件

    logger.info(f'{stock_code}上传解析文件')
    try:
        tmp_key = get_temporary_key(ds_app)
        upload_file_to_cos(ds_app, file_path.file_path,
                           tmp_key['Credentials']['TmpSecretId'],
                           tmp_key['Credentials']['TmpSecretKey'],
                           tmp_key['Credentials']['Token'],
                           tmp_key['Bucket'],
                           tmp_key['UploadPath'])
    except TencentCloudSDKException as e:
        if '450020-文档已存在' == e.message:
            print(f'{stock_code}文档已经上传')
        else:
            raise FileUploadException('文件上传出错')

    up_file_list = get_file_list(ds_app)

    de_sta = ['解析中', '审核中', '学习中']
    while True:
        st = 0
        for fl in up_file_list:
            if fl['StatusDesc'] in de_sta:
                st += 1
                sleep(10)
                break
        up_file_list = get_file_list(ds_app)
        if st > 0:
            continue
        else:
            break

    # 发布
    try:
        publish_app(ds_app)
    except TencentCloudSDKException as e:
        if '450027-没有可发布的文档/问答/拒答/任务流程/应用配置/标签/同义词' == e.message:
            print('已经发布')

    ds_app.bot_app_key = get_app_key(ds_app)

    app_sta = get_app_list(ds_app, ds_app.bot_name)[0]
    if app_sta['AppStatus'] == 3:
        print('已欠费停用')
        delete_app(ds_app)
        sys.exit(0)

    # 使用大模型进行解析
    logger.info(f'{stock_code}解析货币和衍生品')
    sleep(randint(1, 7))
    cont1 = f"参考{file_path.stock_short}{file_path.report_type}中外币货币性项目、外汇风险、外汇敞口等相关内容，整理该公司外币货币性项目， 外币衍生品投资情况，要求获取期末的数据，如有单位换算，请换算，请输出明细数据。最终形成markdown表格，表格要求字段名是资产类别、期末价值、持有明细，请不要使用未搜索到的信息。"
    # cont1 = '你好'
    try:
        rep1 = ds_reply(ds_app, cont1)
        # print(rep1)
    except DSReplyTypeException:
        with open(f'error/{stock_code}.txt', 'w', encoding='utf-8') as f:
            f.write(f'{stock_code}:知识库未调用')
        logger.warning(f'{stock_code}货币未调用知识库')
        delete_app(ds_app)
        sys.exit(0)
    resp1 = par_mk(rep1)
    if resp1.shape[0] > 0:
        curr = pd.read_csv(__file__.replace('get_reply.py', '').replace('\\', '/') + 'currency.csv')
        curr_list = curr.loc[:, '货币名称'].apply(lambda x: x.replace('\xa0', '').split('-')[0]).tolist()
        curr_list += curr.loc[:, '货币名称-繁体'].apply(lambda x: x.replace('\xa0', '').split('-')[0]).tolist()

        res_xj = resp1[resp1.index.isin(curr_list)]
        tk = 1
        if res_xj.shape[0] == 0:
            res_xj = resp1[resp1.index.str.contains('现金') | resp1.index.str.contains('货币性项目') | resp1.index.str.contains('货币资金')]
            tk = 2
        if res_xj.shape[0] > 0:
            if tk == 1:
                res_xj2 = pd.DataFrame([{
                    '项目': '外币货币资金',
                    '金额': sum_amt(res_xj.iloc[:, 0]),
                    '明细': '; '.join((res_xj.iloc[:, 1] + ':' + res_xj.iloc[:, 0].map(str)).tolist())
                }])
            else:
                res_xj2 = pd.DataFrame([{
                    '项目': '外币货币资金',
                    '金额': sum_amt(res_xj.iloc[:, 0]),
                    '明细': '; '.join(res_xj.iloc[:, 1].tolist())
                }])
        else:
            res_xj2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])
        res_ys = resp1[resp1.index.str.contains('衍生') | resp1.index.str.contains('金融資產')]
        if res_ys.shape[0] > 0:
            res_ys2 = pd.DataFrame([{
                '项目': '外汇衍生品',
                '金额': sum_amt(res_ys.iloc[:, 0]),
                '明细': '; '.join(res_ys.iloc[:, 1].tolist())
            }])
        else:
            res_ys2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])
    else:
        res_xj2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])
        res_ys2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])

    app_sta = get_app_list(ds_app, ds_app.bot_name)[0]
    if app_sta['AppStatus'] == 3:
        print('已欠费停用')
        delete_app(ds_app)
        sys.exit(0)

    logger.info(f'{stock_code}解析境外债券和qdii')
    sleep(randint(1, 7))
    cont2 = f"参考{file_path.stock_short}{file_path.report_type}中的金融资产投资相关内容，整理该公司所持有的境外债券（非发行）情况， 投资QDII情况，要求为期末，且有明细。最终形成markdown表格，表格要求字段名是资产类别、期末价值、持有明细，请不要使用未搜索到的信息。"
    try:
        rep2 = ds_reply(ds_app, cont2)
    except DSReplyTypeException:
        with open(f'error/{stock_code}.txt', 'w', encoding='utf-8') as f:
            f.write(f'{stock_code}:知识库未调用')
        logger.warning(f'{stock_code}境外债券未调用知识库')
        delete_app(ds_app)
        sys.exit(0)
    resp2 = par_mk(rep2)
    if resp2.shape[0] > 0:
        res_jw = resp2[resp2.index.str.contains('境外债券')]
        if res_jw.shape[0] > 0:
            res_jw2 = pd.DataFrame([{
                '项目': '境外债券',
                '金额': sum_amt(res_jw.iloc[:, 0]),
                '明细': '; '.join(res_jw.iloc[:, 1].tolist())
            }])
        else:
            res_jw2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])

        res_qdii = resp2[resp2.index.str.contains('QDII') | resp2.index.str.contains('qdii')]
        if res_qdii.shape[0] > 0:
            res_qdii2 = pd.DataFrame([{
                '项目': 'QDII',
                '金额': sum_amt(res_qdii.iloc[:, 0]),
                '明细': '; '.join(res_qdii.iloc[:, 1].tolist())
            }])
        else:
            res_qdii2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])
    else:
        res_jw2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])
        res_qdii2 = pd.DataFrame(None, columns=['项目', '金额', '明细'])

    logger.info(f'{stock_code}结果整合')
    df_res = pd.concat([res_xj2, res_ys2, res_jw2, res_qdii2], axis=0)
    if df_res.shape[0] > 0:
        df_res.loc[:, '金额'] = df_res.loc[:, '金额'].apply(get_num_for)
        # df_res = df_res.iloc[:-1]
        df_res = df_res.set_index('项目')
        df_res = df_res.T
        fun1 = lambda x: '金额：' + x.iloc[0] + '\n' + '明细：' + x.iloc[1]
        df_res = pd.DataFrame(df_res.apply(fun1, axis=0))
        df_res = df_res.T

        col_map = ['外币货币资金', '外汇衍生品', '境外债券', 'QDII']
        no_na_col = [x for x in col_map if x not in df_res.columns.tolist()]
        for no_col in no_na_col:
            df_res.loc[:, no_col] = '金额：0.0\n明细：未披露'
    else:
        df_res = pd.DataFrame({
            '外币货币资金': ['金额：0.0\n明细：未披露'],
            '外汇衍生品': ['金额：0.0\n明细：未披露'],
            '境外债券': ['金额：0.0\n明细：未披露'],
            'QDII': ['金额：0.0\n明细：未披露'],
        })

    df_res.loc[:, '股票代码'] = file_path.stock_code
    df_res.loc[:, '年报类型'] = file_path.report_type
    df_res.loc[:, '解析文件名称'] = file_path.file_title

    if not os.path.exists('res'):
        os.makedirs('res')

    df_res.to_csv(f'res/{file_path.stock_code}.csv', index=False)
    logger.info(f'{stock_code}删除应用')
    delete_app(ds_app)
    logger.info(f'{stock_code}完成')
    #print(rep2)
    

if __name__ == '__main__':
    get_ds_reply('002213')
